package com.example.origin.spider.service;


import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.example.origin.spider.dto.ZwfwSafeDTO;
import com.example.origin.spider.webmagic.ChromeProcessor;
import com.example.origin.spider.properties.ProcessorProperties;
import com.example.origin.spider.utils.HttpClientUtil;
import com.example.origin.spider.utils.OcrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.example.origin.spider.constants.CommonConstant.INTEGER_REGEX;

@Slf4j
@Service("zwfw-safe")
public class ZwfwSafeProcessor extends ChromeProcessor {

    @Autowired
    ObjectMapper objectMapper;

    @Override
    @SneakyThrows
    public void process(ResultItems resultItems, Task task, ProcessorProperties properties) {
        Object o = resultItems.get("result");
        ZwfwSafeDTO zwfwSafeDTO = JSON.parseObject(o.toString(), ZwfwSafeDTO.class);
        Optional.ofNullable(zwfwSafeDTO.getBody())
                .map(ZwfwSafeDTO.BodyDTO::getDataStores).map(ZwfwSafeDTO.BodyDTO.DataStoresDTO::getCreditStore)
                .map(ZwfwSafeDTO.BodyDTO.DataStoresDTO.CreditStoreDTO::getRowSet)
                .map(ZwfwSafeDTO.BodyDTO.DataStoresDTO.CreditStoreDTO.RowSetDTO::getPrimary).ifPresent(e -> {
                    for (ZwfwSafeDTO.BodyDTO.DataStoresDTO.CreditStoreDTO.RowSetDTO.PrimaryDTO primaryDTO : e) {
                        System.out.println(JSONUtil.toJsonStr(primaryDTO));
                    }
                });

    }

    @SneakyThrows
    @Override
    public void process(Page page, ProcessorProperties properties) {
        WebDriver webDriver = getChromeDriver(page);

//        String accountNo = "MA8N854N3";

        otherWinDo(webDriver, other -> {
            if (Objects.equals(other.getTitle(), "弹出公告")) {
                other.close();
            }
        });

        ((JavascriptExecutor) webDriver).executeScript("window.open('http://zwfw.safe.gov.cn/asone/jsp/code.jsp');");

        TimeUnit.SECONDS.sleep(3);

        redoByCondition(webDriver, (driver, fristLogin) -> {
            driver.findElement(By.id("inputOrgCode")).clear();
            driver.findElement(By.id("inputOrgCode")).sendKeys("MA8N854N3");
            driver.findElement(By.id("inputUserCode")).clear();
            driver.findElement(By.id("inputUserCode")).sendKeys("002");
            driver.findElement(By.id("pwdw")).clear();
            driver.findElement(By.id("pwdw")).sendKeys("Lxd1101102");

            otherWinDo(webDriver, other -> {
                if (Objects.equals(other.getTitle(), "弹出公告")) {
                    other.close();
                }
            });
            List<String> codes = new ArrayList<>();
            otherWinDo(driver, other -> {
                if (!fristLogin) {
                    other.navigate().refresh();
                }
                String code = getCode(driver);
                codes.add(code);
            });

            driver.findElement(By.id("check")).clear();
            driver.findElement(By.id("check")).sendKeys(codes.get(0));

            driver.findElement(By.id("loginc")).click();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, driver -> {

            try {
                if (!driver.findElements(By.id("mybuss")).isEmpty()) {
                    otherWinDo(driver, WebDriver::close);
                    return false;
                }
            } catch (UnhandledAlertException e) {
                Map<String, String> alert = e.getAlert();
                log.error(alert.toString(), e);
            }
            return true;
        }, 10);
//        List<JkQuickSpiderAdvanceLoanReport> reports = ExtraUtil.getJkQuickSpiderAdvanceLoanReports(webDriver);
//
//        System.out.println(JSONUtil.toJsonStr(reports));
//        if (1==1){
//            throw new RuntimeException();
//        }


        webDriver.get("http://zwfw.safe.gov.cn/tcorp/e_receiveCreditReportAddQuery.tradedo?current_appCode=SZWG&asone_addr=zwfw.safe.gov.cn:80&asone_id=13073c56-1671288a353-81d76f67e9fa75bc16134518e029baa9&userType=0");
        TimeUnit.SECONDS.sleep(3);
        Set<Cookie> cookies = webDriver.manage().getCookies();
        Optional<String> first = cookies.stream().filter(e -> Objects.equals(e.getName(), "LTPAToken")).map(Cookie::getValue).findFirst();

        String cookiesStr = cookies.stream().map(e -> String.join("=", e.getName(), e.getValue())).collect(Collectors.joining("; "));
        System.out.println(cookiesStr);
        LinkedHashMap<String, String> headers = new LinkedHashMap<>();
        headers.put("Accept", "*/*");
        headers.put("Accept-Language", "zh-CN,zh;q=0.9");
        headers.put("Connection", "keep-alive");
        headers.put("Content-Type", "multipart/form-data");
        headers.put("Cookie", cookiesStr);
        headers.put("Origin", "http://zwfw.safe.gov.cn");
        if (first.isPresent()) {
            String ltpaToken = first.get();
            headers.put("Referer", "http://zwfw.safe.gov.cn/tcorp/e_receiveCreditReportAddQuery.tradedo?current_appCode=SZWG&asone_addr=zwfw.safe.gov.cn%3A80&asone_id=13073c56-1671288a353-81d76f67e9fa75bc16134518e029baa9&userType=0&login_result_sign=login&LTPAToken=" + ltpaToken);
        } else {
            headers.put("Referer", "http://zwfw.safe.gov.cn/tcorp/e_receiveCreditReportAddQuery.tradedo?current_appCode=SZWG&asone_addr=zwfw.safe.gov.cn%3A80&asone_id=13073c56-1671288a353-81d76f67e9fa75bc16134518e029baa9&userType=0&login_result_sign=login");
        }
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0");
        headers.put("X-Requested-With", "XMLHttpRequest");
        headers.put("ajaxRequest", "true");
        String body = "{header:{\"code\":0,\"message\":{\"title\":\"\",\"detail\":\"\"}},body:{dataStores:{\"credit_store\":{rowSet:{\"primary\":[],\"filter\":[],\"delete\":[]},name:\"credit_store\",pageNumber:1,pageSize:15,recordCount:0,parameters:{\"CORPID\":\"MA8N854N3\",\"RPTNO\":\"\",\"PAYTYPE\":\" \",\"startDate\":\"2024-04-01\",\"STARTDATE\":\"2024-04-01\",\"endDate\":\"2024-04-30\",\"ENDDATE\":\"2024-04-30\",\"contractno\":\"\",\"isReported\":\" \",\"unieap_form_Button_0\":\"查询\",\"unieap_form_Button_1\":\"重置\",\"QUERYTYPE\":\"1\",\"SQL_Parameters\":[\"MA8N854N3\",\"2024-04-01\",\"2024-04-30\"],\"TYPE\":\"1\",\"isReportedPayment\":\" \"}}},parameters:{\"synCount\":\"true\"}}}";
        String post = HttpClientUtil.post("http://zwfw.safe.gov.cn/tcorp/delegateAction.do?method=delegateMethod&platform-service-id=e_ReceiveCreditReportService&platform-service-method=paging",
                body, headers, new TypeReference<String>() {
                });
        page.putField("result", post);

    }


    private static void otherWinDo(WebDriver webDriver, Consumer<WebDriver> otherWinConsumer, Boolean backFirst) {
        // 获取所有窗口的句柄
        Set<String> handles = webDriver.getWindowHandles();
        String firstHandle = webDriver.getWindowHandle();
        // 切换到新打开的Tab
        for (String handle : handles) {
            if (!handle.equals(firstHandle)) {
                WebDriver window = webDriver.switchTo().window(handle);
                otherWinConsumer.accept(window);
                break;
            }
        }
        if (backFirst) {
            webDriver.switchTo().window(firstHandle);
        }
    }

    private static void otherWinDo(WebDriver webDriver, Consumer<WebDriver> otherWinConsumer) {
        otherWinDo(webDriver, otherWinConsumer, true);
    }

    @SneakyThrows
    private static String getCode(WebDriver driver) {
        String s = null;
        for (int i = 0; i < 10; i++) {
            byte[] screenshotAs = ((ChromeDriver) driver).getScreenshotAs(OutputType.BYTES);
            TimeUnit.SECONDS.sleep(1);
            List<String> list = OcrUtil.verifyCodes(screenshotAs);
            Optional<String> first = list.stream().filter(e -> e.matches(INTEGER_REGEX)).findFirst();
            if (!first.isPresent()) {
                log.info("第{}次获取验证码，失败，页面刷新", i + 1);
                driver.navigate().refresh();
                driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
            } else {
                s = first.get();
                break;
            }
        }
        return s;
    }

    private static void redoByCondition(WebDriver driver, BiConsumer<WebDriver, Boolean> consumer, Function<WebDriver, Boolean> condition, int maxRepeat) {
        consumer.accept(driver, true);
        Boolean flag = true;
        if (condition.apply(driver)) {
            for (int i = 0; i < maxRepeat; i++) {
                flag = condition.apply(driver);
                if (!flag) {
                    break;
                }
                log.info("【第{}次重新操作】", i + 1);
                consumer.accept(driver, false);
            }
        } else {
            flag = false;
        }
        if (flag) {
            // todo 告警
        }
    }

}
